﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Blog.Types.Repository;
using System.IO;
using System.Reflection;

namespace Blog.Core
{
    public class Factory
    {
        public static Factory _instance;
        private string _dbRepositoryFileName = "Blog.DbRepository.dll";
        private IRepository _repository;

        public static Factory Instance
        {
            get
            {
                if (_instance == null)
                    _instance = new Factory();

                return _instance;
            }
        }

        public IRepository Repository
        {
            get
            {
                //Делаем связывание библиатеки с интерфейсом
                //Можно в config файле написать, можно к сторонним библиатекам обратиться или т.п.
                //Я сделаю через Reflection

                if (_repository == null)
                {
                    string fullName = null;
                    if (string.IsNullOrEmpty(System.AppDomain.CurrentDomain.RelativeSearchPath) && File.Exists(_dbRepositoryFileName))
                    {
                        fullName = _dbRepositoryFileName;
                    }
                    else
                    {
                        string envDir = new DirectoryInfo(System.AppDomain.CurrentDomain.BaseDirectory).Parent.FullName;
                        string conf = 
#if DEBUG
                        "Debug";
#else
                        "Release";
#endif

                        fullName = Path.Combine(envDir, "Bin", conf, _dbRepositoryFileName);
                        if (!File.Exists(fullName))
                            fullName = string.Empty;
                    }

                    if (!string.IsNullOrEmpty(fullName))
                    {
                        Assembly assembly = Assembly.LoadFrom(fullName);
                        if (assembly != null)
                        {
                            Type repType = typeof(IRepository);
                            foreach (Type type in assembly.GetExportedTypes())
                            {
                                if (type.GetInterfaces().Contains(repType))
                                {
                                    _repository = type.GetConstructor(new Type[] { }).Invoke(null) as IRepository;
                                    break;
                                }
                            }
                        }
                    }
                }

                if (_repository == null)
                    throw new ApplicationException("IRepository is not found");

                return _repository;
            }
        }
    }
}
